package com.fingard.dsp.bank.directbank.zjtlcb02;

import net.sf.json.JSONObject;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.AESCipher;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.MD5Util;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;


/**
 * Created by F on 2018/9/13.
 */
public class ZJTLCB02SinglePay extends ZJTLCB02Base implements ISinglePay {

    private static final String INSERTSEQ = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
    private static final String SELECTSEQ = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=?;";

    /**
     * 支付
     * @param p_req1908
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAtsSingle = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        Connection conn= FGBiz.getLocalDbConn();
        try {
            String seqNo=getQryTransID();
            //报文头
            JSONObject jsonHead = new JSONObject();
            jsonHead.put("txSno",p_req1908.singleDetail.askNumber);// 交易流水号
            jsonHead.put("mrchSno",p_req1908.singleDetail.askNumber);// 商户业务编号
            jsonHead.put("bussSeqNo",seqNo);// 银行业务编号
            jsonHead.put("txTime", Format.DateTimeFormat.format(new Date()));// 交易时间
            jsonHead.put("productId",""); // 产品ID
            //报文体
            JSONObject jsonBody = new JSONObject();
            jsonBody.put("sourceType","J01");//	渠道类型
            jsonBody.put("branchId",getBankConfig().getValueAsString("branchId"));//	发送方机构号
            jsonBody.put("userId",getBankConfig().getValueAsString("userId"));//	服务请求者身份
            jsonBody.put("orgSysId",getBankConfig().getValueAsString("orgSysId"));//	原始发起方系统ID
            jsonBody.put("corpCode",getBankConfig().getValueAsString("corpCode"));//	法人类型代码
            jsonBody.put("payDate", DateHelper.convertD10toD8(p_req1908.singleDetail.payDate));//	付款日期
            String realTmFlg=p_req1908.singleDetail.sameBnk;
            if("0".equals(realTmFlg)){//非实时
                realTmFlg="2";
            }
            jsonBody.put("realTmFlg",realTmFlg);//	实时标志：实时为同行支付，非实时为异行支付
            jsonBody.put("extPymtAcctNo",p_req1908.singleDetail.payAct);//	对外付款账号
            jsonBody.put("payerAcctNm",p_req1908.singleDetail.payName);//	付款账户名称
            jsonBody.put("tranAmt",p_req1908.singleDetail.payAmount);//	交易金额
            jsonBody.put("purpose",getPayCode(p_req1908.singleDetail.srcXElement,p_req1908.singleDetail.purpose));//用途  Usage+PostScript
            jsonBody.put("abstract",p_req1908.singleDetail.memo);//	摘要
            jsonBody.put("ccy",convertCurToBank(p_req1908.singleDetail.payCur));//	币种
            jsonBody.put("pyeeCstmrAcct",p_req1908.singleDetail.recAct);//	收款人客户账号
            jsonBody.put("pyeeAcctNm",p_req1908.singleDetail.recName);//	收款人账户名称
            jsonBody.put("payeeOpenBankInterbankNo",p_req1908.singleDetail.cnapsCode);//	收款人开户行联行号
            jsonBody.put("clientNo",bankFront.org);//	客户号
            String data="<?xml version=\"1.0\" encoding=\"utf-8\"?><T><D><M><k>付款账号</k><v>"+p_req1908.singleDetail.payAct+"</v></M><M><k>涉及金额</k><v>"+p_req1908.singleDetail.payAmount+"</v>" +
                    "</M><M><k>收方账号</k><v>"+p_req1908.singleDetail.recAct+"</v></M></D><E><M><k>客户号</k><v>"+bankFront.org+"</v></M></E></T>";
            jsonBody.put("signCert",ukeyData(data).trim());//	签名证书
            //第三方交易流水
            String bankSeqId=getThirdSeqNo();
            //记录ats支付流水号对应的银行支付流水号，供查询状态接口使用
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.singleDetail.askNumber, bankSeqId});
            jsonBody.put("thirdSeqNo",bankSeqId);//	第三方流水号
            //报文内容
            JSONObject jsonReqData = new JSONObject();
            jsonReqData.put("head", jsonHead);
            jsonReqData.put("body", jsonBody);
            //拼接请求json串:data
            JSONObject jsonObject = new JSONObject();
            ZJTLCB02Header tlcb02Header = new ZJTLCB02Header();
            tlcb02Header.seqNO = seqNo;
            //验证开发者
            String appAccessToken=checkDeveloper(seqNo);
            tlcb02Header.appAccessToken = appAccessToken;
            //MD5加密签名串
            WriteBankLogLn("MD5加密原文:"+new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
            String sign= MD5Util.md5_(new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
            tlcb02Header.sign = sign;
            JsonHeader(jsonObject, tlcb02Header);
            jsonObject.put("reqData", jsonReqData);
            WriteBankLogLn("发送银行请求报文原文："+jsonObject.toString());
            //AES加密
            String aesData= AESCipher.encrypt(jsonReqData.toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
            jsonObject.put("reqData", aesData);
            //发送请求报文
            String[] bankResult = sendToBank(jsonObject.toString(),"singleTransferBCDC");
            //处理响应报文
            if (bankResult[0].length() == 0) {
                JSONObject jsonArray = JSONObject.fromObject(bankResult[1].replaceAll(" ",""));
                //AES256解密
                String rspData = AESCipher.decrypt(jsonArray.get("rspData").toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                jsonArray.put("rspData",rspData);
                WriteBankLogLn("银行返回已解密的报文："+jsonArray.toString());
                if(!"".equals(jsonArray.get("errorCode")) && jsonArray.get("errorCode")!=null){
                    if(isActiveRetCode(jsonArray.get("errorCode").toString())) {
                        JSONObject jsonRspData = JSONObject.fromObject(rspData);
                        JSONObject jsonBodys = (JSONObject) jsonRspData.get("body");
                        if(!"".equals(jsonBodys) && jsonBodys!=null){
                            detail.respCode ="0";
                            detail.respInfo = jsonBodys.get("oriRetMsg")!=null?jsonBodys.get("oriRetMsg").toString():"";
                            detail.transState = jsonBodys.get("oriRetCode")!=null?jsonBodys.get("oriRetCode").toString():"3";
                            detail.payInfoCode = detail.transState;
                            detail.reqSeqID = p_req1908.singleDetail.askNumber;
                        }else {
                            detail.respCode = "0";
                            detail.respInfo = "返回rspData或者body内容为空";
                            detail.reqSeqID = p_req1908.singleDetail.askNumber;
                            detail.transState = PaymentState.FAIL_Payment;
                            detail.payInfoCode = bankResult[0];
                        }
                    }else {
                        detail.respCode = "-1";
                        detail.respInfo = jsonArray.get("errorMsg").toString();
                    }
                }else {
                    detail.respCode = "0";
                    detail.respInfo = "响应码未返回";
                    detail.reqSeqID = p_req1908.singleDetail.askNumber;
                    detail.transState = PaymentState.FAIL_Payment;
                    detail.payInfoCode = bankResult[0];
                }
            }else if (bankResult[0].equals(ConnState.FAIL)) {
                detail.respCode = "0";
                detail.respInfo = bankResult[1];
                detail.reqSeqID = p_req1908.singleDetail.askNumber;
                detail.transState = PaymentState.FAIL_Payment;
                detail.payInfoCode = bankResult[0];
            } else{
                detail.respCode ="-1";
                detail.respInfo = bankResult[1];
            }
        }catch (Exception e){
            detail.respCode = "-1";
            detail.respInfo = e.getMessage();
            e.printStackTrace();
            WriteBankLogLn("转账出现异常:"+e);
        }finally {
            conn.close();
        }
        retAtsSingle.writeRetDetail(detail);
        return retAtsSingle;
    }

    /**
     * 查询支付结果
     * @param p_req1944
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAtsSingle = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        Connection conn=FGBiz.getLocalDbConn();
        try{
            if(p_req1944.askNumber.isEmpty()){
                detail.respCode ="-1";
                detail.respInfo = "财务系统交易流水号不能为空";
            }else {
                String seqNo=getQryTransID();
                //报文头
                JSONObject jsonHead = new JSONObject();
                jsonHead.put("txSno",p_req1944.reqHeader.transSeqID);// 交易流水号
                jsonHead.put("mrchSno",p_req1944.reqHeader.transSeqID);// 商户业务编号
                jsonHead.put("bussSeqNo",seqNo);// 银行业务编号
                jsonHead.put("txTime", Format.DateTimeFormat.format(new Date()));// 交易时间
                jsonHead.put("productId",""); // 产品ID
                //报文体
                JSONObject jsonBody = new JSONObject();
                jsonBody.put("sourceType","J01");//	渠道类型
                String seqNo2="";
                Map<String, Object> selMap=JDBCHelper.execQuerySingle(conn,SELECTSEQ,new Object[]{p_req1944.askNumber});
                if(selMap.size()>0){
                    seqNo2=selMap.get("BANKREQSEQID").toString();
                }else {
                    detail.respCode ="-1";
                    detail.respInfo = "系统交易流水号关联映射异常，请检查";
                    retAtsSingle.writeRetDetail(detail);
                    return retAtsSingle;
                }
                jsonBody.put("branchId",getBankConfig().getValueAsString("branchId"));//	发送方机构号
                jsonBody.put("userId",getBankConfig().getValueAsString("userId"));//	服务请求者身份
                jsonBody.put("orgSysId",getBankConfig().getValueAsString("orgSysId"));//	原始发起方系统ID
                jsonBody.put("corpCode",getBankConfig().getValueAsString("corpCode"));//	法人类型代码
                jsonBody.put("extPymtAcctNo",p_req1944.payAct);//对外付款账号
                jsonBody.put("payerAcctNm","");//付款账户名称
                //jsonBody.put("oriTranSeqNo",seqNo2);//原交易流水号
                jsonBody.put("clientNo",bankFront.org);//	客户号
                String data="<?xml version=\"1.0\" encoding=\"utf-8\"?><T><D><M><k>付款账号</k><v>"+p_req1944.payAct+"</v></M><M><k>交易流水</k><v>"+seqNo2+"</v></M></D><E><M><k>客户号</k><v>"+bankFront.org+"</v></M></E></T>";
                WriteBankLogLn("签名请求报文："+data);
                jsonBody.put("signCert",ukeyData(data).trim());//	签名证书
                jsonBody.put("thirdSeqNo",seqNo2);//第三方流水号
                //报文内容
                JSONObject jsonReqData = new JSONObject();
                jsonReqData.put("head", jsonHead);
                jsonReqData.put("body", jsonBody);
                //拼接请求json串:data
                JSONObject jsonObject = new JSONObject();
                ZJTLCB02Header tlcb02Header = new ZJTLCB02Header();
                tlcb02Header.seqNO = seqNo;
                //验证开发者
                String appAccessToken=checkDeveloper(seqNo);
                tlcb02Header.appAccessToken = appAccessToken;
                //MD5加密签名串
                WriteBankLogLn("MD5加密原文:"+new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
                String sign= MD5Util.md5_(new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
                tlcb02Header.sign = sign;
                JsonHeader(jsonObject, tlcb02Header);
                jsonObject.put("reqData", jsonReqData);
                WriteBankLogLn("发送银行请求报文原文："+jsonObject.toString());
                //AES256加密
                String aesData= AESCipher.encrypt(jsonReqData.toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                jsonObject.put("reqData", aesData);
                //发送请求报文
                String[] bankResult = sendToBank(jsonObject.toString(),"singleTranQryBCDC");
                if (bankResult[0].length() == 0) {
                    JSONObject jsonArray = JSONObject.fromObject(bankResult[1].replaceAll(" ",""));
                    //AES256解密
                    String rspData = AESCipher.decrypt(jsonArray.get("rspData").toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                    jsonArray.put("rspData",rspData);
                    WriteBankLogLn("银行返回已解密的报文："+jsonArray.toString());
                    if(!"".equals(jsonArray.get("errorCode")) && jsonArray.get("errorCode")!=null){
                        if(isActiveRetCode(jsonArray.get("errorCode").toString())){
                            JSONObject jsonRspData=JSONObject.fromObject(rspData);
                            JSONObject jsonBodys=(JSONObject)jsonRspData.get("body");
                            if(!"".equals(jsonBodys) && jsonBodys!=null){
                                detail.respCode = "0";//响应码
                                detail.respInfo = jsonBodys.get("oriRetMsg")!=null?jsonBodys.get("oriRetMsg").toString():"";//响应结果
                                detail.reqSeqID = p_req1944.askNumber;//交易流水号
                                detail.payInfoCode = jsonBodys.get("oriRetCode")!=null?jsonBodys.get("oriRetCode").toString():"3";//交易结果：如果银行返回字段缺失，状态标记为处理中
                                detail.transState = detail.payInfoCode;
                            }else {
                                detail.respCode = "-1";
                                detail.respInfo = "返回rspData或者body内容为空";
                            }
                        }else {
                            detail.respCode = "-1";
                            detail.respInfo = jsonArray.get("errorMsg").toString();
                        }
                    }else {
                        detail.respCode = "-1";
                        detail.respInfo = "响应码未返回";
                    }
                }else {
                    detail.respCode = "-1";
                    detail.respInfo = bankResult[1];
                }
            }
        }catch (Exception e){
            detail.respCode = "-1";
            detail.respInfo = e.getMessage();
            e.printStackTrace();
            WriteBankLogLn("查询付款状态异常："+e);
        }finally {
            conn.close();
        }
        retAtsSingle.writeRetDetail(detail);
        return retAtsSingle;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
